package com.controller;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.business.AccountService;
import com.domain.Account;
import com.exception.GenericException;
import com.google.gson.Gson;
import com.utils.Constants;

@Controller
@RequestMapping("/AccountManagement")
public class AccountController {

	@Autowired
	private AccountService accountService;

	// get list all accounts from db.
	@RequestMapping(value = "/getListAccount", method = RequestMethod.POST)
	public ModelAndView getListAccount(
			@RequestParam(value = "start", required = false) Integer start,
			@RequestParam(value = "page", required = false) Integer page) {
		ModelAndView mav = new ModelAndView("admin/getListAccount");
		
		if (start == null) {
			start = Constants.BEGIN;
		}

		if (page == null) {
			int totalAccount = accountService.getTotalAccount();
			if (totalAccount > Constants.LIMIT) {
				page = (int)Math.ceil((double)totalAccount/Constants.LIMIT);
			} else {
				page = 1;
			}
		}
		
		List<Account> lst = accountService.getListAccount(start, Constants.LIMIT);
		mav.addObject("listAccount", lst);
		mav.addObject("page", page);
		mav.addObject("start", start);
		mav.addObject("display", Constants.LIMIT);

		return mav;
	}

	// get list all accounts from db.
	@RequestMapping(value = "/accountLst", method = RequestMethod.GET)
	public ModelAndView accountLst() {
		ModelAndView mav = new ModelAndView("admin/accountManagement");
		return mav;
	}
	
	// create new account
	@SuppressWarnings("deprecation")
	@RequestMapping(value = "/createAccount", method = RequestMethod.POST)
	public ModelAndView addAccount(
			@RequestParam (value = "id_acc", required = false) String accountId,
			@RequestParam (value = "username", required = true) String username,
			@RequestParam (value = "password", required = true) String password,
			@RequestParam (value = "email", required = true) String email) {
		ModelAndView mav = new ModelAndView(Constants.JSON_PAGE);
		Map<String, String> map = new HashMap<String, String>();
		
		Account acc = new Account();
		try {
		// url encode and encode base64
		acc.setUsername(new String(Base64.encodeBase64(URLEncoder.encode(username).getBytes())));
		acc.setPassword(new String(Base64.encodeBase64(password.getBytes())));
		acc.setEmail(email);
		
		
			if (StringUtils.isNotEmpty(accountId) && StringUtils.isNumeric(accountId)) {
				acc.setId(Integer.parseInt(accountId));
				accountService.updateAccount(acc);
				map.put("message", "Update successfully!");
			} else {
				accountService.createAccount(acc);
				map.put("message", "Create successfully!");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			map.put("message", "Error occurs!");
		}
		
		mav.addObject(Constants.JSON_ATRIBUTE_NAME, new Gson().toJson(map));
		return mav;
	}
	
	// delete account
	@RequestMapping(value = "/deleteAccount", method = RequestMethod.POST)
	public ModelAndView deleteAccount(
			@RequestParam (value="id_acc", required = true) Integer accountId) {
		ModelAndView mav = new ModelAndView(Constants.JSON_PAGE);
		Map<String, String> map = new HashMap<String, String>();
		
		try {
			accountService.deleteAccount(accountId);
			map.put("status", "success");
		} catch (Exception ex) {
			ex.printStackTrace();
			map.put("status", "fail");
		}
		
		mav.addObject(Constants.JSON_ATRIBUTE_NAME, new Gson().toJson(map));
		
		return mav;
	}
	
	//404 page
	@RequestMapping("/404")
	public ModelAndView getErrorPage() {
		return new ModelAndView("404");
	}

}
